package cjj;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.*;

@WebServlet("/admin/login")
public class AdminLoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 验证输入
        if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
            request.setAttribute("errorMessage", "用户名或密码不能为空");
            request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
            return;
        }

        // 打印登录尝试信息（用于调试）
        System.out.println("登录尝试 - 用户名: " + username);

        Connection conn = null;
        int retryCount = 0;
        int maxRetries = 3;

        while (retryCount < maxRetries) {
            try {
                // 手动加载驱动类
                Class.forName("com.mysql.cj.jdbc.Driver");
                System.out.println("驱动类加载成功！");

                // 数据库连接和查询
                conn = DriverManager.getConnection(
                        "jdbc:mysql://localhost:3306/webproject_2025?useSSL=false&serverTimezone=UTC",
                        "root", "root");

                // 验证数据库连接
                if (conn.isClosed()) {
                    throw new SQLException("数据库连接已关闭");
                }
                System.out.println("数据库连接成功");
                break;
            } catch (ClassNotFoundException e) {
                System.err.println("驱动类未找到异常: " + e.getMessage());
                e.printStackTrace();
                request.setAttribute("errorMessage", "登录失败: 数据库驱动加载失败，请联系管理员");
                request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
                return;
            } catch (SQLException e) {
                retryCount++;
                System.err.println("数据库连接失败，尝试第 " + retryCount + " 次重试...");
                if (retryCount == maxRetries) {
                    System.err.println("SQL 错误: " + e.getMessage());
                    System.err.println("SQL 状态码: " + e.getSQLState());
                    System.err.println("错误代码: " + e.getErrorCode());
                    e.printStackTrace();

                    // 根据不同的SQL状态码提供更具体的错误信息
                    String errorMessage = "数据库错误";
                    if (e.getSQLState() != null) {
                        switch (e.getSQLState()) {
                            case "42S02": // 表不存在
                                errorMessage = "数据库表结构错误，请检查";
                                break;
                            case "28000": // 权限错误
                                errorMessage = "数据库访问权限不足";
                                break;
                            case "08001": // 连接拒绝
                                errorMessage = "无法连接到数据库服务器";
                                break;
                            default:
                                errorMessage = "数据库操作失败: " + e.getMessage();
                        }
                    }

                    request.setAttribute("errorMessage", errorMessage);
                    request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
                    return;
                }
                try {
                    Thread.sleep(1000); // 等待1秒后重试
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        }

        try {
            // 准备 SQL 查询
            String sql = "SELECT * FROM admin WHERE username = ? AND password = ?";
            System.out.println("执行 SQL: " + sql);
            System.out.println("参数 1: " + username);
            System.out.println("参数 2: " + hashPassword(password));

            try (PreparedStatement stmt = conn.prepareStatement(sql)) {
                stmt.setString(1, username);
                stmt.setString(2, hashPassword(password));

                try (ResultSet rs = stmt.executeQuery()) {
                    if (rs.next()) {
                        // 登录成功
                        System.out.println("登录成功 - 管理员ID: " + rs.getInt("id"));

                        // 存储管理员信息到Session
                        request.getSession().setAttribute("adminId", rs.getInt("id"));
                        request.getSession().setAttribute("adminUsername", rs.getString("username"));

                        // 重定向到管理仪表盘（直接指向JSP）
                        response.sendRedirect(request.getContextPath() + "/cjj/admin_dashboard.jsp");
                    } else {
                        // 登录失败
                        System.out.println("登录失败 - 用户名或密码错误");
                        request.setAttribute("errorMessage", "用户名或密码错误");
                        request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
                    }
                }
            }
        } catch (SQLException e) {
            // 打印详细的 SQL 错误信息
            System.err.println("SQL 错误: " + e.getMessage());
            System.err.println("SQL 状态码: " + e.getSQLState());
            System.err.println("错误代码: " + e.getErrorCode());
            e.printStackTrace();

            // 根据不同的SQL状态码提供更具体的错误信息
            String errorMessage = "数据库错误";
            if (e.getSQLState() != null) {
                switch (e.getSQLState()) {
                    case "42S02": // 表不存在
                        errorMessage = "数据库表结构错误，请检查";
                        break;
                    case "28000": // 权限错误
                        errorMessage = "数据库访问权限不足";
                        break;
                    case "08001": // 连接拒绝
                        errorMessage = "无法连接到数据库服务器";
                        break;
                    default:
                        errorMessage = "数据库操作失败: " + e.getMessage();
                }
            }

            request.setAttribute("errorMessage", errorMessage);
            request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
        } catch (Exception e) {
            // 捕获其他异常
            System.err.println("其他错误: " + e.getMessage());
            e.printStackTrace();
            request.setAttribute("errorMessage", "系统错误: " + e.getMessage());
            request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
        } finally {
            // 关闭数据库连接
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 检查是否已登录
        if (request.getSession().getAttribute("adminId") != null) {
            response.sendRedirect(request.getContextPath() + "/cjj/admin_dashboard.jsp");
        } else {
            // 未登录，转发到登录页面
            request.getRequestDispatcher("/cjj/admin_login.jsp").forward(request, response);
        }
    }

    // 密码哈希方法
    private String hashPassword(String password) {
        try {
            // 创建SHA-256哈希实例
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = md.digest(password.getBytes("UTF-8"));

            // 将字节数组转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = String.format("%02x", b);
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException | java.io.UnsupportedEncodingException e) {
            throw new RuntimeException("密码哈希失败", e);
        }
    }
}